﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Net;
using HtmlAgilityPack;
using NFLManager.Properties;

namespace NFLManager
{
    public class Fetch
    {
        
        protected Fetch() { }

        protected static Fetch _fetch = null;

        public static Fetch Istance
        {
            get { return _fetch ?? (_fetch = new Fetch()); }
        }


        #region fields

        private static readonly HtmlWeb _web = new HtmlWeb();
        private static HtmlDocument _doc = null;

        #endregion
        

        #region utilities

        private HtmlDocument LoadUrl(string url)
        {
            HtmlDocument result = null;
            bool pass;
            int i = 0;
            do
            {
                try
                {
                    result = _web.Load(url);
                    pass = true;
                }
                catch (WebException)
                {
                    i++;
                    if (i > 10) throw new Exception();
                    pass = false;
                }
            } while (!pass);

            return result;
        }

        #endregion


        public DataTable Roster(string team)
        {
            var url = String.Format(Settings.Default.URL_ROSTER, team);
            var doc = LoadUrl(url);
            
            //table
            var id = "result";
            var html = doc.GetElementbyId(id);

            return Utilities.Istance.DataTableFromHtml("Roster", html);
        }

        public DataTable Matchs(string season, byte week)
        {
            var url = String.Format(Settings.Default.URL_MATCHS, season, week);
            var doc = LoadUrl(url).DocumentNode;
            
            //divs
            var @class = "list-matchup-row-team";
            var divs = doc.Descendants("div").Where(d => d.Attributes.Contains("class") && d.Attributes["class"].Value == @class);

            //create matchs html table


            return Utilities.Istance.DataTableFromHtml("Matchs", html);
        }

        public DataTable PlayersStats(string season, byte week, string showCategory)
        {
            var url = String.Format(Settings.Default.URL_PLAYERS_STATS, season, week, showCategory);
            var doc = LoadUrl(url).DocumentNode;
            
            //table
            var @class = "data-table1";
            var html = doc.Descendants("table").Where(d => d.Attributes.Contains("class") && d.Attributes["class"].Value == @class).FirstOrDefault();

            return Utilities.Istance.DataTableFromHtml("PlayersStats", html);
        }

        public DataTable Injuries(string team, byte week)
        {
            var url = String.Format(Settings.Default.URL_INJURIES, team, week);
            var doc = LoadUrl(url).DocumentNode;
            
            //table
            var @class = "data-table1";
            var html = doc.Descendants("table").Where(d => d.Attributes.Contains("class") && d.Attributes["class"].Value == @class).FirstOrDefault();

            return Utilities.Istance.DataTableFromHtml("Injuries", html);
        }

        public DataTable Standings()
        {
            var url = String.Format(Settings.Default.URL_STANDINGS);
            var doc = LoadUrl(url).DocumentNode;
            
            //table
            var @class = "data-table1";
            var html = doc.Descendants("table").Where(d => d.Attributes.Contains("class") && d.Attributes["class"].Value == @class).FirstOrDefault();

            return Utilities.Istance.DataTableFromHtml("Standings", html);
        }

        #region future_delete

        //private string GetUrl(string page, string week = null, string season = null, string showCategory = null, string category = null, string team = null)
        //{

        //    switch (page)
        //    {
        //        case "schedule":
        //            return
        //                Settings.Default.URL_MATCHS +
        //                "/" +
        //                season +
        //                "/REG" +
        //                week;

        //        case "roster":
        //            return
        //                Settings.Default.URL_ROSTER +
        //                "?" +
        //                "team=" + team;

        //        case "players":
        //            return
        //                Settings.Default.URL_PLAYERS_STATS_WEEKS + "?" +
        //                "season=" + season + "&" +
        //                "week=" + week + "&" +
        //                "showCategory=" + showCategory;

        //        case "injuries":
        //            return
        //                Settings.Default.URL_INJURIES_TEAMS + "?" +
        //                "week=" + week;

        //        case "standings":
        //            return
        //                Settings.Default.URL_STANDING_CATEGORIES + "?" +
        //                "category=" + category;
        //    }
        //    return null;
        //}

        //public HtmlNode GetPlayers(string team)
        //{
        //    int i = 0;

        //    //preleva la tabella da modificare
        //    _doc = _web.Load(GetUrl("roster", team: team));
        //    var oldTable = _doc.GetElementbyId("result");

        //    //crea la nuova tabella
        //    HtmlNode result = HtmlNode.CreateNode("<table colspan =\"11\"></table>");
        //    HtmlNode htmlTitleRow = HtmlNode.CreateNode("<tr></tr>");

        //    //modifica le intestazioni
        //    const string r0c1 = "<td>Name</td>";
        //    const string r0c2 = "<td>Surname</td>";
        //    const string r0c3 = "<td>Ref</td>";
        //    foreach (var col in oldTable.Descendants("tr").ElementAt(0).Descendants("th"))
        //    {
        //        if (i == 1)
        //        {
        //            htmlTitleRow.AppendChild(HtmlNode.CreateNode(r0c1));
        //            htmlTitleRow.AppendChild(HtmlNode.CreateNode(r0c2));
        //            htmlTitleRow.AppendChild(HtmlNode.CreateNode(r0c3));
        //            i++;
        //        }
        //        else
        //        {
        //            var htmlCol = String.Format("<td>{0}</td>", CleanValue(col.InnerText));
        //            htmlTitleRow.AppendChild(HtmlNode.CreateNode(htmlCol));
        //            i++;
        //        }
        //    }
        //    result.AppendChild(htmlTitleRow);

        //    //ricostruisce la tabella
        //    var rows = oldTable.Descendants("tr").Skip(1);
        //    foreach (var row in rows)
        //    {
        //        HtmlNode htmlRow = HtmlNode.CreateNode("<tr></tr>");
        //        //ignora le righe dei gicoatori con numero di maglia inesistente
        //        if (row.Descendants("td").ElementAt(0).InnerText != "")
        //        {
        //            i = 0;
        //            foreach (var col in row.Descendants("td"))
        //            {
        //                if (i == 1)
        //                {
        //                    var htmlCol1 = String.Format("<td>{0}</td>", CleanValue(col.InnerText.Split(',')[1]));
        //                    htmlRow.AppendChild(HtmlNode.CreateNode(htmlCol1));
        //                    var htmlCol2 = String.Format("<td>{0}</td>", CleanValue(col.InnerText).Split(',')[0]);
        //                    htmlRow.AppendChild(HtmlNode.CreateNode(htmlCol2));
        //                    var htmlCol3 = String.Format("<td>{0}</td>", Settings.Default.URL_NFL + col.Descendants("a").First().GetAttributeValue("href", ""));
        //                    htmlRow.AppendChild(HtmlNode.CreateNode(htmlCol3));
        //                    i++;
        //                }
        //                else
        //                {
        //                    var htmlCol = String.Format("<td>{0}</td>", CleanValue(col.InnerText));
        //                    htmlRow.AppendChild(HtmlNode.CreateNode(htmlCol));
        //                    i++;
        //                }
        //            }
        //            result.AppendChild(htmlRow);
        //        }
        //    }
        //    return result;
        //}

        //public HtmlNode GetPlayerRecentGames(string url)
        //{
        //    _doc = LoadUrl(url);
        //    var result = _doc.DocumentNode.Descendants("table").First(t => t.Descendants("tr").ElementAt(0).Descendants("td").ElementAt(0).Descendants("span").ElementAt(0).InnerText == "Recent Games");
        //    return result;
        //}

        //public HtmlNode GetPlayerRegularSeason(string url)
        //{

        //    int i = 0;
        //    int w = 0;
        //    //preleva la tabella da modificare
        //    var oldTable = GetTableFromTitle(url, "Regular Season");

        //    //crea la nuova tabella
        //    HtmlNode result = HtmlNode.CreateNode("<table></table>");

        //    var rows = oldTable.Descendants("tr").Where(r => r.Descendants("td").Count() > 1 && r.Descendants("td").ElementAt(1).InnerText != "Bye");
        //    rows.Last().Remove();
        //    rows.ToList().ForEach(r => result.AppendChild(r));

        //    //crea le nuove intestazioni della tabella e rimpiazzo quelle esistenti ( string -> CreateNode -> ReplaceChild).
        //    string r1c1 = "<td>TEAM</td>";
        //    string r1c2 = "<td>OPP</td>";
        //    string r1c3 = "<td>AH</td>";
        //    result.SelectNodes("tr")[1].ReplaceChild(HtmlNode.CreateNode(r1c1), result.SelectNodes("tr")[1].SelectNodes("td")[1]);
        //    result.SelectNodes("tr")[1].ReplaceChild(HtmlNode.CreateNode(r1c2), result.SelectNodes("tr")[1].SelectNodes("td")[2]);
        //    result.SelectNodes("tr")[1].ReplaceChild(HtmlNode.CreateNode(r1c3), result.SelectNodes("tr")[1].SelectNodes("td")[3]);

        //    //modifica il contenuto dei dati
        //    i = 2;
        //    LoadDictionaries();
        //    foreach (var row in result.SelectNodes("tr").Skip(2))
        //    {
        //        //preleva la stringa contenente le squadre del match
        //        var teams = row.SelectNodes("td")[2].Descendants("a").ElementAt(0).GetAttributeValue("href", "").Split('/')[5];
        //        var oppTeam = CleanValue(row.SelectNodes("td")[2].Descendants("a").ElementAt(1).InnerText);
        //        var homeTeam = _dTeamIdtoDesc.FirstOrDefault(e => e.Value == teams.Split('@')[1].Trim('@')).Key;
        //        var awayTeam = _dTeamIdtoDesc.FirstOrDefault(e => e.Value == teams.Split('@')[0].Trim('@')).Key;
        //        //interpreta la stringa prelevata in precedenza e ricava, la squdra di casa e quella ospite
        //        if (oppTeam == homeTeam)
        //        {
        //            result.SelectNodes("tr")[i].ReplaceChild(HtmlNode.CreateNode("<td>" + awayTeam + "</td>"), result.SelectNodes("tr")[i].SelectNodes("td")[1]);
        //            result.SelectNodes("tr")[i].ReplaceChild(HtmlNode.CreateNode("<td>" + homeTeam + "</td>"), result.SelectNodes("tr")[i].SelectNodes("td")[2]);
        //            result.SelectNodes("tr")[i].ReplaceChild(HtmlNode.CreateNode("<td>" + "AWAY" + "</td>"), result.SelectNodes("tr")[i].SelectNodes("td")[3]);
        //            i++;
        //        }
        //        else
        //        {
        //            result.SelectNodes("tr")[i].ReplaceChild(HtmlNode.CreateNode("<td>" + homeTeam + "</td>"), result.SelectNodes("tr")[i].SelectNodes("td")[1]);
        //            result.SelectNodes("tr")[i].ReplaceChild(HtmlNode.CreateNode("<td>" + awayTeam + "</td>"), result.SelectNodes("tr")[i].SelectNodes("td")[2]);
        //            result.SelectNodes("tr")[i].ReplaceChild(HtmlNode.CreateNode("<td>" + "HOME" + "</td>"), result.SelectNodes("tr")[i].SelectNodes("td")[3]);
        //            i++;
        //        }
        //    }

        //    w = 2;
        //    foreach (var row in result.SelectNodes("tr").Skip(2))
        //    {
        //        i = 0;
        //        foreach (var col in row.SelectNodes("td"))
        //        {
        //            if (col.InnerText.Contains("--"))
        //            {
        //                switch (result.SelectNodes("tr")[1].SelectNodes("td")[i].InnerText)
        //                {
        //                    case "Sck":
        //                        result.SelectNodes("tr")[w].ReplaceChild(HtmlNode.CreateNode("<td>" + "0" + "</td>"),
        //                                                                 result.SelectNodes("tr")[w].SelectNodes("td")[i
        //                                                                     ]);
        //                        break;
        //                    case "Pct":
        //                        result.SelectNodes("tr")[w].ReplaceChild(HtmlNode.CreateNode("<td>" + "0.0" + "</td>"),
        //                                                                 result.SelectNodes("tr")[w].SelectNodes("td")[i
        //                                                                     ]);
        //                        break;
        //                    case "Avg":
        //                        result.SelectNodes("tr")[w].ReplaceChild(HtmlNode.CreateNode("<td>" + "0.0" + "</td>"),
        //                                                                 result.SelectNodes("tr")[w].SelectNodes("td")[i
        //                                                                     ]);
        //                        break;
        //                    case "Lng":
        //                        result.SelectNodes("tr")[w].ReplaceChild(HtmlNode.CreateNode("<td>" + "0" + "</td>"),
        //                                                                 result.SelectNodes("tr")[w].SelectNodes("td")[i
        //                                                                     ]);
        //                        break;
        //                    default:
        //                        result.SelectNodes("tr")[w].ReplaceChild(HtmlNode.CreateNode("<td>" + "0" + "</td>"),
        //                                                                 result.SelectNodes("tr")[w].SelectNodes("td")[i
        //                                                                     ]);
        //                        break;
        //                }
        //            }
        //            else
        //            {
        //                switch (result.SelectNodes("tr")[1].SelectNodes("td")[i].InnerText)
        //                {
        //                    case "Lng":
        //                        result.SelectNodes("tr")[w].ReplaceChild(
        //                            HtmlNode.CreateNode("<td>" + result.SelectNodes("tr")[w].SelectNodes("td")[i
        //                                                             ].InnerText.Trim('T') + "</td>"),
        //                            result.SelectNodes("tr")[w].SelectNodes("td")[i
        //                                ]);
        //                        break;
        //                    case "Sck":
        //                        result.SelectNodes("tr")[w].ReplaceChild(
        //                            HtmlNode.CreateNode("<td>" + result.SelectNodes("tr")[w].SelectNodes("td")[i
        //                                                             ].InnerText.Split('.')[0] + "</td>"),
        //                            result.SelectNodes("tr")[w].SelectNodes("td")[i
        //                                ]);
        //                        break;
        //                }
        //            }
        //            i++;
        //        }
        //        w++;
        //    }

        //    return result;
        //}

        //private HtmlNode GetTableFromTitle(string url, string title)
        //{
        //    _doc = LoadUrl(url);
        //    var result = _doc.DocumentNode.Descendants("table").First(t => t.Descendants("tr").ElementAt(0).Descendants("td").ElementAt(0).InnerText == title);
        //    return result;
        //}

        //public DataTable Injuries(HtmlNodeCollection scripts)
        //{
        //    string hometeam, awayTeam;
        //    DataTable result = EmptyInjuries();

        //    foreach (var script in scripts)
        //    {

        //        var text = script.InnerText.Replace("\n\r", "").Replace("\n", "").Replace("\r", "").Replace(" ", "");

        //        var vars = text.Substring(text.IndexOf("var") + 3, text.IndexOf(";") - text.IndexOf("var") - 2);

        //        Dictionary<string, string> keyValuePairs = vars.Split(',')
        //        .Select(value => value.Split('='))
        //        .ToDictionary(pair => pair[0].Replace("\n", "").Replace("'", ""), pair => pair[1].Replace("\n", "").Replace("'", ""));

        //        string away = keyValuePairs["awayAbbr"];
        //        string home = keyValuePairs["homeAbbr"];

        //        var dataAwayJson = text.Substring(text.IndexOf("dataAway") + 11).Substring(0, (text.Substring(text.IndexOf("dataAway") + 11)).IndexOf("]") - 2).Replace("},{", ";");
        //        var dataHomeJson = text.Substring(text.IndexOf("dataHome") + 11).Substring(0, (text.Substring(text.IndexOf("dataHome") + 11)).IndexOf("]") - 2).Replace("},{", ";");

        //        var findDataAwayJson = dataAwayJson.StartsWith("player");
        //        var findDataHomeJson = dataHomeJson.StartsWith("player");

        //        GetInjuriesDataTable(findDataAwayJson, dataAwayJson, away, findDataHomeJson, dataHomeJson, home);
        //    }

        //    return result;
        //}

        #endregion
        
    }
}
